package com.zzyl.service.impl;


import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import com.aliyun.oss.common.utils.ResourceManager;
import com.zzyl.base.ResponseResult;
import com.zzyl.constant.AdminCacheConstant;
import com.zzyl.constant.SuperConstant;
import com.zzyl.dto.ResourceDto;
import com.zzyl.entity.Dept;
import com.zzyl.entity.Resource;
import com.zzyl.enums.BasicEnum;
import com.zzyl.exception.BaseException;
import com.zzyl.mapper.ResourceMapper;
import com.zzyl.mapper.RoleMapper;
import com.zzyl.mapper.RoleResourceMapper;
import com.zzyl.service.ResourceService;
import com.zzyl.utils.EmptyUtil;
import com.zzyl.utils.NoProcessing;
import com.zzyl.utils.StringUtils;
import com.zzyl.vo.DeptVo;
import com.zzyl.vo.ResourceVo;
import com.zzyl.vo.TreeItemVo;
import com.zzyl.vo.TreeVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.Caching;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

@Service
@Slf4j
public class ResourceServiceImpl implements ResourceService {

    @Autowired
   private ResourceMapper resourceMapper;

    @Autowired
    RoleResourceMapper roleResourceMapper;

    @Override
   @Cacheable(cacheNames = AdminCacheConstant.RESOURCE_LIST, key = "#resourceDto.hashCode")
    public List<ResourceVo> findResourceList(ResourceDto resourceDto) {

        List<Resource> resourceList = resourceMapper.selectList(resourceDto);

        return BeanUtil.copyToList(resourceList, ResourceVo.class);
    }

    @Cacheable(cacheNames = AdminCacheConstant.RESOURCE_TREE)
    @Override
    public TreeVo ResourceTreeVo(ResourceDto resourceDto) {

    //新创建对象
        ResourceDto dto = ResourceDto.builder().build();

        //将资源列表转成树形结构
        List<Resource> resourceList = resourceMapper.selectList(dto);
        log.info("资源数量:{}", resourceList.size());

         if(resourceList==null || resourceList.size()==0){
             throw new RuntimeException("资源信息未定义");
         }
         //将这个父节点的菜单数转成树形结构Tree
        Resource root = new Resource();
         root.setResourceNo(SuperConstant.ROOT_PARENT_ID);
         root.setResourceName("智慧养老");

        List<TreeItemVo> itemsvo = new ArrayList<>();

        recursionTreeItem(resourceList, root, itemsvo);

        TreeVo treeVo = new TreeVo(itemsvo);

        return treeVo;
    }
    //    需要删除换
    @Caching(
            evict = {
                    @CacheEvict(cacheNames = AdminCacheConstant.RESOURCE_TREE,allEntries = true),
                    @CacheEvict(cacheNames = AdminCacheConstant.RESOURCE_LIST,allEntries = true)
            }
    )
    @Override
    public Boolean createResource(ResourceDto resourceDto) {
        //将dto转换成实体
        Resource resource = BeanUtil.toBean(resourceDto, Resource.class);

        //资源有禁用和启用，如果父资源是禁用，那么子资源也应该禁用
      Resource parentResource =  resourceMapper.selectParentByNo(resource.getParentResourceNo());
        if (parentResource.getResourceType().equals("r")){
            throw  new BaseException(BasicEnum.BUTTON_NOT_HAVE_CHILD);

        }



      // return setDataState(parentResource.getDataState());

        //资源的层级，只支持三级
        boolean isIgnore = true; //如果是按钮，就false
        if(StringUtils.isNotEmpty(resourceDto.getResourceType())
        && resourceDto.getResourceType().equals(SuperConstant.BUTTON)){
            isIgnore = false;
        }
      String resourceNo =  createResourceNo(resource.getParentResourceNo(),isIgnore);
        resource.setResourceNo(resourceNo);
        resourceMapper.insert(resource);
        return true;

    }


    //删除菜单
    @Override
    public void deleteByresourceNo(List<String> resourceNo) {
        if (hasChildByMenuId(resourceNo)){
            throw new RuntimeException("存在子菜单,不允许删除");

        }
     Resource resource =    resourceMapper.selectByResourceNo(resourceNo);
        if (resource==null || resource.getDataState().equals(SuperConstant.DATA_STATE_0)){
            throw new RuntimeException("菜单启用状态,不能删除");
        }
        resourceMapper.deleteByresourceNo(resourceNo);




    }
    /**
     * 判断是否有子菜单
     * @param resourceNo
     * @return
     */
    private boolean hasChildByMenuId(List<String> resourceNo) {
        int result = resourceMapper.hasChildByMenuId(resourceNo);
        return result > 0 ? true : false;
    }




    private String createResourceNo(String parentResourceNo,boolean isIgnore) {
        // 菜单不能大于三级，可以通过父亲的编号来判断，如果父亲已经是三级了，就不能再加了
//* 平台 100 000 000 000 000-->100--1
//* 第1层：100 001 000 000 000-->100 001---2
//* 第2层：100 001 001 000 000-->100 001 001--3
//* 第3层：100 001 001 001 000-->100 001 001 001--4
//* 第4层：100 001 001 001 001 001-->100 001 001 001 001--5
        if (isIgnore && (NoProcessing.processString(parentResourceNo).length() / 3) >= 5) {
            throw new BaseException(BasicEnum.RESOURCE_DEPTH_UPPER_LIMIT);

        }
//现在有了父亲的编号
        ResourceDto parentResourceDto = ResourceDto.builder().parentResourceNo(parentResourceNo).build();
        List<Resource> childrenReresourcesList = resourceMapper.selectList(parentResourceDto);
        if (EmptyUtil.isNullOrEmpty(childrenReresourcesList)) {
            //如果父亲没有儿子，那么父亲就是叶子节点
            return NoProcessing.createNo(parentResourceNo, false);
        } else {
            //父亲有儿子，找到儿子中最大的编号
            Long maxNo = childrenReresourcesList.stream().map(item -> {
                return Long.valueOf(item.getResourceNo());
            }).max(Comparator.comparing(i -> i)).get();
            return NoProcessing.createNo(String.valueOf(maxNo), true);
        }

    }


    private void recursionTreeItem(List<Resource> resourceList, Resource root, List<TreeItemVo> itemsvo) {
        TreeItemVo rootVo = TreeItemVo.builder().id(root.getResourceNo()).label(root.getResourceName()).build();
              //将所有的资源遍历，一一的问，你的爸爸是我吗？
        List<Resource> rootChildVo = resourceList.stream().filter(item -> item.getParentResourceNo().equals(root.getResourceNo()))
                .collect(Collectors.toList());

        //判断儿子s是否是空的
        if (!EmptyUtil.isNullOrEmpty(rootChildVo)){
            List<TreeItemVo> childList =new ArrayList<>();
            //问儿子，你有儿子吗？
            rootChildVo.forEach(item->{
                //一个一个的问
                recursionTreeItem(resourceList,item, childList);

            });

            rootVo.setChildren(childList);

        }


        itemsvo.add(rootVo);


    }




}


